package forum;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import parser.ParserAnnotation;

/**
 * This class assumes that the user either let the class decide keys topicId,
 * itemId, postId, sentenceId _or_ that the user decide keys by using set<key>Id
 * and _NOT_ both
 * 
 * @author aek
 * 
 */

public class ForumFactory implements Serializable {

	private static final long serialVersionUID = -751387812619085182L;

	private HashMap<String, ForumItem> items;
	private HashMap<String, ForumTopic> topics;
	private HashMap<String, ForumTag> tags;

	private SimpleDateFormat sdf;
	private SimpleDateFormat tsdf;

	private int itemId = 1;
	private int topicId = 1;

	private int tagId = 1;

	private int sentId = 1;
	private int postId = 0;

	public Map<String, ForumItem> getItems() {
		return items;
	}

	public Map<String, ForumTopic> getTopics() {
		return topics;
	}

	public Map<String, ForumTag> getTags() {
		return tags;
	}

	public ForumFactory() {
		items = new HashMap<String, ForumItem>();
		topics = new HashMap<String, ForumTopic>();

		// ForumTopic nullTopic = new ForumTopic(topicId++, "NoTopic");
		// ForumItem nullItem = new ForumItem(itemId++, "NoItem");
		// nullItem.setTopic(nullTopic);
		// topics.put("NoTopic", nullTopic);
		// items.put("NoItem", nullItem);

		tags = new HashMap<String, ForumTag>();
		// ForumTag nullTag = new ForumTag(1, "NoTag");
		// ForumCategory nullCategory = new ForumCategory(1, "NoCategory");
		// tags.put("NoTag", nullTag);
		// categories.put("NoCategory", nullCategory);

		sdf = new SimpleDateFormat("yyyy-MM-dd");
		tsdf = new SimpleDateFormat("HH:mm:ss");
	}

	/**
	 * Creates a forum topic as well if it doesn't already exist.
	 */
	public synchronized ForumItem makeItem(String itemName, String topicName) {
		if (items.containsKey(itemName)) {
			ForumItem it = items.get(itemName);
			return it;
		}
		ForumTopic topic = topics.get(topicName);
		if (topic == null) {
			topic = new ForumTopic(topicId++, topicName);
			topics.put(topicName, topic);
		}
		ForumItem item = new ForumItem(itemId++, itemName);
		item.setTopic(topic);
		items.put(itemName, item);
		return item;
	}

	public synchronized ForumTag makeTag(String tagName) {
		if (tags.containsKey(tagName)) {
			ForumTag tag = tags.get(tagName);
			return tag;
		}
		ForumTag tag = new ForumTag(tagId++, tagName);
		tags.put(tagName, tag);
		return tag;
	}

	public synchronized ForumSentence makeSent(String text, ForumPost post) {
		ForumSentence fs = new ForumSentence(sentId++, text, post.getPostId());
		post.addSentence(fs);
		return fs;
	}

	public synchronized ForumPost makePost(String title, ParserAnnotation pa,
			String source, String poster, String postDate, String time,
			String hyperlink, String forumCategory,
			ArrayList<ForumTag> forumTags) {
		return new ForumPost(++postId, poster, postDate, time, title,
				hyperlink, forumCategory, forumTags, pa, source);
	}

	public synchronized ForumPost makePost(String title, ParserAnnotation pa,
			String source) {
		ArrayList<ForumTag> tagList = new ArrayList<ForumTag>();
		tagList.add(this.makeTag("NoTag"));
		return makePost(title, pa, source, "NoPoster",
				date(System.currentTimeMillis()),
				time(System.currentTimeMillis()), "NoLink", "NoCategory",
				tagList);
	}

	public synchronized ForumPost makePost(String title, ParserAnnotation pa,
			String source, String poster, String link) {
		ArrayList<ForumTag> tagList = new ArrayList<ForumTag>();
		tagList.add(this.makeTag("NoTag"));
		return makePost(title, pa, source, poster,
				date(System.currentTimeMillis()),
				time(System.currentTimeMillis()), link, "NoCategory", tagList);
	}

	public synchronized String date(long date) {
		return sdf.format(new Date(date));
	}

	public synchronized String time(long date) {
		return tsdf.format(new Date(date));
	}

	public void store() throws IOException {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				"fac.object"));
		oos.writeObject(this);
		oos.flush();
		oos.close();
	}

	public static ForumFactory load() throws IOException,
			ClassNotFoundException {
		File f = new File("fac.object");
		if (!f.exists())
			return new ForumFactory();
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
		ForumFactory fac = (ForumFactory) (ois.readObject());
		fac.sdf = new SimpleDateFormat("yyyy-MM-dd");
		fac.tsdf = new SimpleDateFormat("HH:mm:ss");
		ois.close();
		return fac;
	}
}
